package com.example.webrtcdemo.webrtc

import android.util.Log
import com.zhangke.websocket.SocketListener
import com.zhangke.websocket.WebSocketHandler
import com.zhangke.websocket.WebSocketManager
import com.zhangke.websocket.WebSocketSetting
import com.zhangke.websocket.response.ErrorResponse
import com.zhangke.websocket.util.LogUtil
import org.java_websocket.framing.Framedata
import org.json.JSONObject
import org.webrtc.IceCandidate
import org.webrtc.SessionDescription
import java.nio.ByteBuffer

/**
 * @作者: smile
 * @时间: 2025/10/9 20:38
 * @描述:
 **/
class SignalingClient(
    private val serverUrl: String,
    private val localUserId: String
) {
    private val TAG = "SignalingClient"
    private var webSocketManager: WebSocketManager? = null
    private var signalingListener: SignalingListener? = null
    private var isConnected = false
    private val webSocketUtils: WebSocketUtils by lazy { WebSocketUtils.getInstance() }
    // 信令消息类型
    enum class MessageType {
        OFFER, ANSWER, ICE_CANDIDATE, USER_ONLINE, USER_OFFLINE, ERROR, HEARTBEAT
    }

    // 信令监听接口
    interface SignalingListener {
        fun onSignalingConnected()
        fun onOfferReceived(offer: SessionDescription, fromUserId: String)
        fun onAnswerReceived(answer: SessionDescription, fromUserId: String)
        fun onIceCandidateReceived(candidate: IceCandidate)
        fun onUserOnline(userId: String)
        fun onUserOffline(userId: String)
        fun onConnectionError(message: String)
        fun onConnectionClosed()
    }

    /**
     * 连接信令服务器
     */
    fun connect() {
        try {
            Log.d(TAG, "正在连接信令服务器: $serverUrl")
            if (!webSocketUtils.isInit) {
                webSocketUtils.init()
            }
            // 1.2 监听WebSocket连接状态和消息（核心：接收信令并转发）
            webSocketUtils.mWebSocketManager?.addListener(createSocketListener())/*object : SocketListener {
                override fun onConnected() {
                    LogUtil.d(TAG, "信令连接成功（通过WebSocketUtils）")
                    signalingListener?.onSignalingConnected()
                }

                override fun onConnectFailed(throwable: Throwable) {
                    val errorMsg = "信令连接失败：${throwable.message ?: "未知错误"}"
                    LogUtil.e(TAG, errorMsg, throwable)
                    signalingListener?.onConnectionError(errorMsg)
                }

                override fun onDisconnect() {
                    LogUtil.d(TAG, "信令连接断开")
                    signalingListener?.onConnectionClosed()
                }

                override fun onSendDataError(errorResponse: ErrorResponse) {
                    val errorMsg = "信令发送失败：${errorResponse.description ?: "未知错误"}"
                    LogUtil.e(TAG, errorMsg)
                    signalingListener?.onConnectionError(errorMsg)
                }

                // 1.3 接收WebSocket消息，解析为WebRTC信令
                override fun <T> onMessage(msg: String, t: T) {
                    LogUtil.d(TAG, "收到信令消息: $msg")
                    try {
                        if (msg.startsWith("0") || msg == "1") {
                            LogUtil.d(TAG, "跳过服务器控制消息，无需解析: $msg")
                            return // 不执行后续解析逻辑
                        }
                        handleSignalingMessage(msg)
                    } catch (e: Exception) {
                        LogUtil.e(TAG, "解析信令消息失败", e)
                    }
                }

                // 忽略二进制消息（WebRTC信令默认用文本JSON）
                override fun <T> onMessage(bytes: ByteBuffer, t: T) {}
                override fun onPing(framedata: Framedata?) {
                    LogUtil.e(TAG, "===心跳onPong=== $framedata")
                }

                override fun onPong(framedata: Framedata?) {
                    LogUtil.e(TAG, "===心跳onPong=== $framedata")
                }

            })

            // 1.4 启动WebSocket连接（WebSocketUtils内部已处理重连）
            webSocketUtils.connectWebSocket()*/
        } catch (e: Exception) {
            Log.e(TAG, "信令客户端初始化失败", e)
            signalingListener?.onConnectionError("初始化失败: ${e.message}")
        }
    }

    /**
     * 创建WebSocket监听器
     */
    private fun createSocketListener(): SocketListener {
        return object : SocketListener {
            override fun onConnected() {
                Log.d(TAG, "信令服务器连接成功")
                isConnected = true
                // 发送用户上线消息
                sendUserOnline()
                signalingListener?.onSignalingConnected()
            }

            override fun onConnectFailed(throwable: Throwable) {
                val errorMsg = "信令服务器连接失败: ${throwable.message}"
                Log.e(TAG, errorMsg, throwable)
                isConnected = false
                signalingListener?.onConnectionError(errorMsg)
            }

            override fun onDisconnect() {
                Log.d(TAG, "信令服务器断开连接")
                isConnected = false
                signalingListener?.onConnectionClosed()
            }

            override fun onSendDataError(errorResponse: ErrorResponse) {
                Log.e(TAG, "信令发送失败: ${errorResponse.description}")
            }

            override fun <T> onMessage(message: String, t: T) {
                Log.d(TAG, "收到信令消息: $message")
                handleSignalingMessage(message)
            }

            override fun <T> onMessage(bytes: ByteBuffer, t: T) {
                // 处理二进制消息（WebRTC通常使用文本消息）
                Log.d(TAG, "收到二进制消息，长度: ${bytes.remaining()}")
            }

            override fun onPing(framedata: Framedata?) {
                Log.d(TAG, "收到Ping帧$framedata")
            }

            override fun onPong(framedata: Framedata?) {
                Log.d(TAG, "收到Pong帧$framedata")
            }
        }
    }

    /**
     * 处理信令消息
     */
    private fun handleSignalingMessage(message: String) {
        try {
            if(message.startsWith("0") ||message.startsWith("1")){
                LogUtil.d(TAG, "===接收到的消息为===$message")
                return
            }
            val jsonObject = JSONObject(message)
            val type = jsonObject.getString("type")
            val fromUserId = jsonObject.optString("fromUserId", "")
            val toUserId = jsonObject.optString("toUserId", "")

            // 检查消息是否是发给自己的
            if (toUserId.isNotEmpty() && toUserId != localUserId) {
                Log.d(TAG, "忽略非目标用户消息，目标用户: $toUserId, 本地用户: $localUserId")
                return
            }

            when (type) {
                "OFFER" -> handleOfferMessage(jsonObject, fromUserId)
                "ANSWER" -> handleAnswerMessage(jsonObject, fromUserId)
                "ICE_CANDIDATE" -> handleIceCandidateMessage(jsonObject)
                "USER_ONLINE" -> handleUserOnlineMessage(fromUserId)
                "USER_OFFLINE" -> handleUserOfflineMessage(fromUserId)
                "ERROR" -> handleErrorMessage(jsonObject)
                "HEARTBEAT" -> handleHeartbeatMessage(fromUserId)
                else -> Log.w(TAG, "未知消息类型: $type")
            }
        } catch (e: Exception) {
            Log.e(TAG, "信令消息解析失败: ${e.message}", e)
        }
    }

    /**
     * 处理OFFER消息
     */
    private fun handleOfferMessage(jsonObject: JSONObject, fromUserId: String) {
        try {
            val sdp = jsonObject.getString("sdp")
            val offer = SessionDescription(SessionDescription.Type.OFFER, sdp)
            Log.d(TAG, "收到OFFER from: $fromUserId")
            signalingListener?.onOfferReceived(offer, fromUserId)
        } catch (e: Exception) {
            Log.e(TAG, "处理OFFER消息失败", e)
        }
    }

    /**
     * 处理ANSWER消息
     */
    private fun handleAnswerMessage(jsonObject: JSONObject, fromUserId: String) {
        try {
            val sdp = jsonObject.getString("sdp")
            val answer = SessionDescription(SessionDescription.Type.ANSWER, sdp)
            Log.d(TAG, "收到ANSWER from: $fromUserId")
            signalingListener?.onAnswerReceived(answer, fromUserId)
        } catch (e: Exception) {
            Log.e(TAG, "处理ANSWER消息失败", e)
        }
    }

    /**
     * 处理ICE候选消息
     */
    private fun handleIceCandidateMessage(jsonObject: JSONObject) {
        try {
            val candidateJson = jsonObject.getJSONObject("candidate")
            val sdpMid = candidateJson.getString("sdpMid")
            val sdpMLineIndex = candidateJson.getInt("sdpMLineIndex")
            val candidate = candidateJson.getString("candidate")

            val iceCandidate = IceCandidate(sdpMid, sdpMLineIndex, candidate)
            Log.d(TAG, "收到ICE候选: $iceCandidate")
            signalingListener?.onIceCandidateReceived(iceCandidate)
        } catch (e: Exception) {
            Log.e(TAG, "处理ICE候选消息失败", e)
        }
    }

    /**
     * 处理用户上线消息
     */
    private fun handleUserOnlineMessage(userId: String) {
        Log.d(TAG, "用户上线: $userId")
        signalingListener?.onUserOnline(userId)
    }

    /**
     * 处理用户下线消息
     */
    private fun handleUserOfflineMessage(userId: String) {
        Log.d(TAG, "用户下线: $userId")
        // 可以在这里处理用户下线逻辑
        signalingListener?.onUserOffline(userId)
    }

    /**
     * 处理错误消息
     */
    private fun handleErrorMessage(jsonObject: JSONObject) {
        val errorMsg = jsonObject.optString("message", "未知错误")
        Log.e(TAG, "收到错误消息: $errorMsg")
        signalingListener?.onConnectionError(errorMsg)
    }

    /**
     * 处理心跳消息
     */
    private fun handleHeartbeatMessage(fromUserId: String) {
        Log.d(TAG, "收到心跳 from: $fromUserId")
        // 可以回复心跳确认
        sendHeartbeatAck(fromUserId)
    }

    /**
     * 发送用户上线消息
     */
    private fun sendUserOnline() {
        val message = createMessage(MessageType.USER_ONLINE, null, null)
        sendMessage(message)
    }

    /**
     * 发送用户下线消息
     */
    fun sendUserOffline() {
        val message = createMessage(MessageType.USER_OFFLINE, null, null)
        sendMessage(message)
    }

    /**
     * 发送OFFER消息
     */
    fun sendOffer(offer: SessionDescription, toUserId: String) {
        val message = createMessage(MessageType.OFFER, toUserId, offer.description)
        Log.d(TAG, "发送OFFER to: $toUserId")
        sendMessage(message)
    }

    /**
     * 发送ANSWER消息
     */
    fun sendAnswer(answer: SessionDescription, toUserId: String) {
        val message = createMessage(MessageType.ANSWER, toUserId, answer.description)
        Log.d(TAG, "发送ANSWER to: $toUserId")
        sendMessage(message)
    }

    /**
     * 发送ICE候选消息
     */
    fun sendIceCandidate(candidate: IceCandidate, toUserId: String) {
        val candidateJson = JSONObject().apply {
            put("sdpMid", candidate.sdpMid)
            put("sdpMLineIndex", candidate.sdpMLineIndex)
            put("candidate", candidate.sdp)
        }

        val message = JSONObject().apply {
            put("type", MessageType.ICE_CANDIDATE.name)
            put("fromUserId", localUserId)
            put("toUserId", toUserId)
            put("candidate", candidateJson)
            put("timestamp", System.currentTimeMillis())
        }.toString()

        Log.d(TAG, "发送ICE候选 to: $toUserId")
        sendMessage(message)
    }

    /**
     * 发送心跳消息
     */
    fun sendHeartbeat(toUserId: String? = null) {
        val message = createMessage(MessageType.HEARTBEAT, toUserId, null)
        sendMessage(message)
    }

    /**
     * 发送心跳确认
     */
    private fun sendHeartbeatAck(toUserId: String) {
        val message = createMessage(MessageType.HEARTBEAT, toUserId, "ack")
        sendMessage(message)
    }

    /**
     * 创建标准消息格式
     */
    private fun createMessage(type: MessageType, toUserId: String?, sdp: String?): String {
        return JSONObject().apply {
            put("type", type.name)
            put("fromUserId", localUserId)
            put("toUserId", toUserId ?: JSONObject.NULL)
            put("sdp", sdp ?: JSONObject.NULL)
            put("timestamp", System.currentTimeMillis())
        }.toString()
    }

    /**
     * 发送消息到信令服务器
     */
    private fun sendMessage(message: String) {
        if (!isConnected) {
            Log.e(TAG, "WebSocket未连接，无法发送消息")
            signalingListener?.onConnectionError("WebSocket未连接")
            return
        }

        try {
            webSocketManager?.send(message)
            Log.d(TAG, "消息发送成功: ${message}...")
        } catch (e: Exception) {
            Log.e(TAG, "消息发送失败", e)
            signalingListener?.onConnectionError("消息发送失败: ${e.message}")
        }
    }

    /**
     * 设置信令监听器
     */
    fun setSignalingListener(listener: SignalingListener) {
        this.signalingListener = listener
    }

    /**
     * 断开连接
     */
    fun disconnect() {
        Log.d(TAG, "断开信令连接")
        isConnected = false
        sendUserOffline()
        webSocketManager?.disConnect()
        webSocketManager = null
    }

    /**
     * 检查连接状态
     */
    fun isConnected(): Boolean {
        return isConnected
    }

    /**
     * 重新连接
     */
    fun reconnect() {
        Log.d(TAG, "重新连接信令服务器")
        disconnect()
        connect()
    }
}